package com.hq.door.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;

import com.hq.door.dao.IBaseDao;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements IBaseDao<T> {
	private Class<T> entityClass;
	
	@Resource(name = "sessionFactory")
	public void setSuperSessionFactory(SessionFactory sessionFactory) {
		this.setSessionFactory(sessionFactory);
		//super.setSessionFactory(sessionFactory);
	}
	
	public BaseDaoImpl() {
		Type type = this.getClass().getGenericSuperclass();
		// 判断是否可以获取到类型
		if(type instanceof ParameterizedType){
			//
			ParameterizedType pType = (ParameterizedType)this.getClass().getGenericSuperclass();		
			//
			Type[] types = pType.getActualTypeArguments();
			//实体类的类型
			entityClass =(Class<T>) types[0];
		}
	}

	@Override
	public void save(T entity) {
		this.getHibernateTemplate().save(entity);
		//保存的时候可能存在运行时异常
		//throw new RuntimeException("锟斤拷菘锟斤拷锟斤拷锟届常锟斤拷");
	}

	@Override
	public void update(T entity) {
		this.getHibernateTemplate().update(entity);
	}

	@Override
	public void delete(T entity) {
		this.getHibernateTemplate().delete(entity);
	}

	@Override
	public void saveOrUpdate(T entity) {
		this.getHibernateTemplate().saveOrUpdate(entity);
	}

	@Override
	public T get(int id) {
		return this.getHibernateTemplate().get(entityClass, id);
	}

	@Override
	public <T> List<T> findPageObjects(final String hql, final int pageStart, final int pageSize ,final Object... conditions) {
		List list = (List)this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				Query query = session.createQuery(hql);				
				for(int i=0;i<conditions.length;i++){
					query.setParameter(i, conditions[i]);
				}
				query.setFirstResult(pageStart);
				query.setMaxResults(pageSize);
				return query.list();
			}
		});
		return list;
	}


	@Override
	public <T> List<T> find(String hql, Object[] values) {
		// TODO Auto-generated method stub
		return (List<T>) this.getHibernateTemplate().find(hql, values);
	}


	@Override
	public <T> List<T> queryList(final String hql, final Object... conditions) {
		List list = (List) this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				Query query = session.createQuery(hql);				
				for(int i=0;i<conditions.length;i++){
					query.setParameter(i, conditions[i]);
				}
				return query.list();
			}
		});
		return list;
	}

	@Override
	public T queryOne(final String hql, final Object... conditions) {
		Object object = this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				Query query = session.createQuery(hql);				
				for(int i=0;i<conditions.length;i++){
					query.setParameter(i, conditions[i]);
				}
				return query.uniqueResult();
			}
		});
		return (T) object;
	}

	@Override
	public int getCount(final String hql, final Object... conditions) {
		
		int resu =  (Integer) this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				Query query = session.createQuery(hql);				
				for(int i=0;i<conditions.length;i++){
					query.setParameter(i, conditions[i]);
				}
				return Integer.valueOf(query.iterate().next().toString());
			}
		});
		return resu;
	}

	@Override
	public int modifyTeacherInfo(final String hql, final Object... conditions) {
		
		int resu =  (int) this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				Query query = session.createQuery(hql);				
				for(int i=0;i<conditions.length;i++){
					query.setParameter(i, conditions[i]);
				}
				return query.executeUpdate();
			}
		});
		return resu;
	}

}
